package stark.app.function.watermark;

import android.graphics.Bitmap;
import android.view.MotionEvent;
import android.view.View;

import com.blankj.utilcode.util.FileUtils;
import com.blankj.utilcode.util.ImageUtils;
import com.blankj.utilcode.util.PathUtils;
import com.blankj.utilcode.util.ToastUtils;
import com.stark.picselect.PhotoSelectorBuilder;
import com.stark.picselect.config.PhotoConfig;
import com.stark.picselect.entity.SelectMediaEntity;
import com.stark.picselect.interfaces.OnSelectResultListener;
import com.stark.watermark.lib.pic.WatermarkRedoUndoController;
import com.stark.watermark.lib.pic.WatermarkUtils;

import org.opencv.android.OpenCVLoader;

import java.io.File;
import java.util.List;

import io.reactivex.rxjava3.core.ObservableEmitter;
import stark.app.R;
import stark.app.databinding.FragmentWatermarkImgDemoBinding;
import stark.common.basic.base.BaseNoModelFragment;
import stark.common.basic.redo.RedoUndoController;
import stark.common.basic.utils.RxUtil;
import stark.common.basic.utils.StkPermissionHelper;
import stark.common.basic.utils.WorkPathUtil;

/**
 * Author：daizhongbin on 2023/12/15
 * Email：1027154338@qq.com
 * Desc:
 */
public class WatermarkImgDemoFragment extends BaseNoModelFragment<FragmentWatermarkImgDemoBinding> implements RedoUndoController.IListener<String> {

    private String mOriginalPath;
    private WatermarkRedoUndoController mRedoUndoController;
    private String mCurrentPath;
    private boolean hasUseWatermark;

    @Override
    protected int onCreate() {
        return R.layout.fragment_watermark_img_demo;
    }

    @Override
    protected void initView() {
        mCurrentPath = "";

        // OpenCV初始化
        OpenCVLoader.initDebug();
        // 设置裁剪框大小(不设置默认为图片大小)
        mDataBinding.cropImageView.setInitialFrameScale(0.5f);
        // 初始化监听器(撤销、重做按钮的使用)-->记得在onDestroy()注销监听器
        mRedoUndoController = new WatermarkRedoUndoController();
        mRedoUndoController.addListener(this);

        checkToShowUndoRedo();

        mDataBinding.btPicSelect.setOnClickListener(this);
        mDataBinding.btPicChange.setOnClickListener(this);
        mDataBinding.btPicShow.setOnClickListener(this);
        mDataBinding.btPicHide.setOnClickListener(this);
        mDataBinding.btPicRevoke.setOnClickListener(this);
        mDataBinding.btPicRedo.setOnClickListener(this);
        mDataBinding.btPicSave.setOnClickListener(this);

        // 原图对比
        mDataBinding.btPicContrast.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (!hasUseWatermark) {
                    ToastUtils.showShort("暂未制作新的图片，无法比对");
                    return true;
                }
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        mDataBinding.cropImageView.setCropEnabled(false);
                        mDataBinding.cropImageView.setImageBitmap(ImageUtils.getBitmap(mOriginalPath));
                        break;
                    case MotionEvent.ACTION_UP:
                        mDataBinding.cropImageView.setImageBitmap(ImageUtils.getBitmap(mCurrentPath));
                        break;
                }
                return true;
            }
        });
    }

    @Override
    protected void initData() {

    }

    @Override
    public void onClick(View view) {
        int id = view.getId();
        if (id == R.id.btPicRevoke) {
            mRedoUndoController.undo();
        } else if (id == R.id.btPicRedo) {
            mRedoUndoController.redo();
        } else if (id == R.id.btPicSave) {
            saveAlbum();
        } else if (id == R.id.btPicChange) {
            showDialog("擦除水印中...");
            RxUtil.create(new RxUtil.Callback<String>() {
                @Override
                public void doBackground(ObservableEmitter<String> emitter) {
                    String removeWatermarkPath = WatermarkUtils.removeWatermarkPath(mCurrentPath,
                            mDataBinding.cropImageView.getActualCropRect());
                    emitter.onNext(removeWatermarkPath);
                }

                @Override
                public void accept(String removeWatermarkPath) {
                    dismissDialog();
                    mCurrentPath = removeWatermarkPath;
                    mRedoUndoController.addDo(removeWatermarkPath);
                    showPic(removeWatermarkPath);
                }
            });
        } else if (id == R.id.btPicSelect) {
            selectPic();
        } else if (id == R.id.btPicShow) {
            mDataBinding.cropImageView.setCropEnabled(true);
        } else if (id == R.id.btPicHide) {
            mDataBinding.cropImageView.setCropEnabled(false);
        }
    }

    @Override
    public void onDoChanged() {
        checkToShowUndoRedo();
    }

    @Override
    public void onRedo(String value) {
        mCurrentPath = value;
        showPic(value);
        checkToShowUndoRedo();
    }

    @Override
    public void onUndo(String value) {
        mCurrentPath = value;
        showPic(value);
        checkToShowUndoRedo();
    }

    private void checkToShowUndoRedo() {
        hasUseWatermark = mRedoUndoController.canUndo();
        mDataBinding.btPicRevoke.setVisibility(mRedoUndoController.canUndo() ? View.VISIBLE : View.GONE);
        mDataBinding.btPicRedo.setVisibility(mRedoUndoController.canRedo() ? View.VISIBLE : View.GONE);
    }

    private void saveAlbum() {
        // 保存到本地相册有3方法
        // 方法1--对应WatermarkUtils.removeWatermarkPath()
        // 使用FileP2pUtil.copyPrivateImgToPublic();
        // 方法2--对应WatermarkUtils.removeWatermarkBitmap()
        // 使用ImageUtils.save2Album();
        // 方法3--直接获取当前所展示的图片bitmap
        // ImageUtils.save2Album(mDataBinding.cropImageView.getImageBitmap(), Bitmap.CompressFormat.PNG);
        showDialog("保存中...");
        RxUtil.create(new RxUtil.Callback<File>() {
            @Override
            public void doBackground(ObservableEmitter<File> emitter) {
                File file = ImageUtils.save2Album(mDataBinding.cropImageView.getImageBitmap(), Bitmap.CompressFormat.PNG);
                emitter.onNext(file);
            }

            @Override
            public void accept(File obj) {
                dismissDialog();
                if (obj != null) {
                    ToastUtils.showShort("已保存到本地相册");
                } else {
                    ToastUtils.showShort("保存失败");
                }
            }
        });
    }

    private void selectPic() {
        StkPermissionHelper.permission(StkPermissionHelper.Permission.ACCESS_IMAGE_VIDEO)
                .reqPermissionDesc("选择图片，需申请文件存储权限，是否申请权限？")
                .callback(new StkPermissionHelper.ACallback() {
                    @Override
                    public void onGranted() {
                        PhotoSelectorBuilder.builder(getActivity())
                                .mode(PhotoConfig.Mode.PHOTO)
                                .isCopyToPrivate(false)
                                .minCount(1)
                                .maxCount(1)
                                .listener(new OnSelectResultListener<List<SelectMediaEntity>>() {
                                    @Override
                                    public void onResult(List<SelectMediaEntity> data) {
                                        mCurrentPath = mOriginalPath = data.get(0).getPath();
                                        mRedoUndoController.addDo(mOriginalPath);
                                        showPic(mOriginalPath);
                                    }
                                });
                    }
                })
                .request();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mRedoUndoController.delListener(this);
        mRedoUndoController.clear();
        FileUtils.delete(PathUtils.getFilesPathExternalFirst() + WorkPathUtil.WORK_IMG_DIR);
    }

    /**
     * 展示图片
     *
     * @param selectPath 图片路径
     */
    private void showPic(String selectPath) {
        mDataBinding.cropImageView.setImageBitmap(ImageUtils.getBitmap(selectPath));
    }
}
